Hallo Ich bin gerade dabei die Kommunikation zwischen zwei Treibern zu implementieren. Zu diesem Thema suche zurzeit einige Beispiele bzw. gute Tipps wie man dies am besten realisieren kann! Habe schon von IRPs gelesen wollte aber Fragen ob dies die einzige Möglichkeit ist!? Die Treiber laufen unter windows. MFG fresh
Häh? Wieso zwei sollen denn zwei Treiber miteinander kommunizieren? Ein Treiber kommuniziert mit der Hardware und mit einer höheren Schicht des OS oder mit der Anwendung aber nicht mit einem anderen Treiber. Kannst Du das mal erläutern? Gruss Treiber
Hallo Also es ist so. Ich habe einen TDI Treiber der sich um Netzwerkpakete kümmert. Dieser soll bei bestimmten Paketen diese an ein weiteres Kernelmodul weitergeben welches die Pakete bearbeitet und teilweise wieder an den TD Treiber zum versenden übergibt! Daher müssen diese beiden Kernelmodule miteinander kommunizieren. MFG Fresh
Hallo Man könnte es layered driver nennen. Es ist ein TDI Driver für eine NIC welcher mit einen Kernel Modul kommunizeren soll! Diese Kernel Modul soll jedoch von mehreren Treibern daten bekommen und an diese Weiteschicken! Wenn jedes Kernel Modul und jeder Treiber eine IRP hat sollte dies doch funktionieren oder? MFG Fresh
Manomann, soviel geballtes Halbwissen auf einem Haufen... >Häh? Wieso zwei sollen denn zwei Treiber miteinander kommunizieren? Meinst du etwa, dass so komplexe Funktionalitäten und Abstraktionen wie bspw. bei Audio, Netzwerk, USB uvm. in jew. einem Monoliten zusammenkompiliert sind? >Der saubere Weg geht über DeviceIoControl Das ist viel zu allgemein formuliert und hilft dem Thread-Starter nicht, denn DeviceIoControls sind IRPs eines bestimmten Typs, die jedoch nicht in jedem Fall zur Anwendung kommen... Wenn du TDI machen möchtest, kannst du im DDK ganz gut nachlesen, wies geht. Dort gibts auch Beispiele, wie man sich in den Stack (also die Layer) einklinken kann. Kannst im Netz auch nach folgenden Schlüsselworten suchen, die liefern die ein paar Beispiele: eine einfache UDP Verbindung kannste mit ZwCreateFile auf L"\\Device\\Udp" öffnen. Referenz auf Device-Objekt: ObReferenceObjectByHandle zum Senden: TDI_SEND_DATAGRAM zum Datenempfang per UDP/TCP TDI_SET_EVENT_HANDLER TDI_EVENT_RECEIVE_DATAGRAM zur Kommunikation zw. Treibern allg: ZWCreateFile, dann IRP bauen und IoCallDriver aufrufen
Hallo Danke erstmals für die Antworten. Ich habe schon eine TDI Modul welches mir UDP emofäng und auch versenden kann. Wollte in diesen Driver in der DriverEntry Funktion den Befehl IoCreateDevice ausführen um irps auf diesen Treiber setzen zu können. Leider fehlt mir allerdings das DriverObject welches normallerweise von der DriverEntry Funktion übergeben wird! Liegt das daran das sich der Treiber nicht auf eine NIC sondern auf einen Port bindet? Wie kann ich das sonst lösen oder ist das der falsche Ansatz? Werde mir auch die einzelnene von euch angeführten Funktionen ansehen! MFG Fresh
Hallo Habe bei der vorigen Nachricht vergessen dazuzuschreiben wie ich es implementieren will. Jeder Treiber bzw. jedes Kernel Modul ruft die Funktion IoCreateDevice auf um sich am I/O Manager anzumelden. Danach kann jeder Treiber bzw. jedes Kernel Modul mit einen anderen Treiber bzw. Kernel Modul über IRPs kommunizieren! Dieser Ansatz sollte doch funktionieren oder liege ich da falsch? So sollte es doch möglich sein das mein TDI Treiber meinen Kernelmodul mitteilt das Daten angekommen sind und diese weiterleitet oder? MFG Fresh
steht doch da: ZwCreateFile ObReferenceObjectByHandle DDK lesen bildet...
Hallo Habe schon das Internet durchforstet und die MSDN aber irgendwie finde ich nirgends eine Link zu einer Anleitung welche Funktionen der Treiber nun enthalten muss. ich dachte das ich beim DriverObject nur die Majorfunktionen einstellen muss und danach mit einen anderen Treiber auf diese einen IRP machen kann und das ich dazu im zweiten Treiber nur die Funktion IoGetDeviceObjectPointer benötige aber so geht es anscheinend nicht. Ich habe aber nirgends etwas von zwCreateFile gelesen. Hat vielleicht irgendwer eine guten Link oder eine Beschreibung dazu? DANKE MFG Fresh
Hallo Habe die Kommunikation zwischen 2 KErnel Modulen hinbekommen. Ich schicke von Modul A nach Modul B einen write Request und Modul B geht in die Majorfunktion für wirte Requests. Dort wird derzeit nur eine Meldung ausgegeben und die IoCompleteRequest(Irp, IO_NO_INCREMENT) ausgeführt. Leider funktioniert dies nur beim ersten mal danach kann ich Modul B nicht mehr beenden! In Modul A wird auch der IRP mit der Free Funktion wieder freigegeben. Weis jemand woran das liegen kann? MFG fresh
@ Heinz >>Häh? Wieso zwei sollen denn zwei Treiber miteinander kommunizieren? >Meinst du etwa, dass so komplexe Funktionalitäten und Abstraktionen wie >bspw. bei Audio, Netzwerk, USB uvm. in jew. einem Monoliten >zusammenkompiliert sind? Nein, das habe ich auch nicht geschrieben. Ich habe bisjetzt garkeine Meinung geäussert sondern eine Frage gestellt. Ich habe nur gefragt: "Häh? Wieso zwei sollen denn zwei Treiber miteinander kommunizieren?" Alles was ich als Antworten sehe sind: Layer, nicht verschiedene Treiber. Das ist sicherlich ein Definitionsproblem, aber IMHO kommunizieren nicht Treiber miteinander, sondern eine Applikation benutzt Treiber. Oder sind hier die beiden Treiber in jeweils einem von zwei verschiedenen Rechnern gemeint? Gruss Leser
fresh wrote: > Hallo > > Habe die Kommunikation zwischen 2 KErnel Modulen hinbekommen. Ich > schicke von Modul A nach Modul B einen write Request und Modul B geht in > die Majorfunktion für wirte Requests. Und wenn du jetzt statt des wirte ein IOCTL nimmst, dann bist du auf dem richtigen Weg. Für das Handling der IRPs suchst du dir am besten Treiberbeispiele aus dem DDK (heißt jetzt WDK) - das Standardbeispiel dort ist der Toaster, der enthält so ziemlich alle Konstellationen.
Hallo Wenn ich nun das write in IOCTL ändere muss ich im Modul welches den IRP Empfängt mittels einer Case anweisung herausfinden was zu tun ist also entweder schreiben oder lesen!? weil das IOCTL gibts ja gar nicht laut msdn. Es gibt als Vergleich Device_control. es muss doch mit den Write auch gehen oder? Das wird ja nicht der Grund sein warum mein empfangentes Modul sich nicht mehr beenden lässt oder? MFG fresh
fresh wrote: > nicht laut msdn. Es gibt als Vergleich Device_control. Das meine ich. Genau IRP_MJ_DEVICE_CONTROL > es muss doch mit den Write auch gehen oder? Da wäre ich sehr vorsichtig, denn Windows ist nicht Open Source und man kann nicht einfach nachsehen, was los ist, wenn es irgendwo klemmt - und das tut es erfahrungsgemäß gerne. MSD ist als Quelle zum Treiberschreiben nicht ausreichend. Hast du mal auf dem OSR-Link nachgelesen, das ich oben angegeben hatte? Das hier scheint auch ganz interessant zu sein: http://www.acc.umu.se/~bosse/ Wenn du dort in FileDisk nachsiehst, findest du die Behandlung von IRP_MJ_DEVICE_CONTROL. Mach es so, wie die MS-Fuzzies das auch machen, dann bist du zwar nicht unbedingt auf der sicheren Seite, aber zumindest nich sehr weit davon.
@ Leser
>IMHO kommunizieren nicht Treiber miteinander
deine HO ist für mich und den Rest der Welt total egal...
Heinz wrote:
> deine HO ist für mich und den Rest der Welt total egal...
Deine auch.
@Uhu
>Deine auch.
bleib du mal bei deiner "Sicherheitseinrichtung" die 200mA Pulse
von der Phase zum Schutzleiter schickt...
Hallo Also wie bereits ober geschrieben funktioniert die Kommunikation meiner beiden Driver mittlerweile. Leider nur beim ersten mal. Wenn ich danach deiden Driver beenden will lässt sich der TDI Treiber (IRP Empfänger) nicht beenden. Er sagt immer das sich in seinen Zustand nicht beenden lässt! Woran kann das liegen?? Im driver der den IRP sendet gebe ich diesen auch weider Frei und im empfänger habe ich auch den Befehl zum zurückgeben an den IO Controller drin! MFG fresh
Warum sollten Treiber nicht miteinander Kommunizieren können? Unter Linux sollte es einfach sein. Funktion in Treiber A exportieren, genauso in Treiber B und schon kann auf den anderen Treiber auf diese Funktionen zugegriffen werden, nur muss man sicherstellen, daß der andre Treiber auch wirklich schon läuft.
>Unter Linux sollte es einfach sein.
Frage lesen
Frage verstehen
überlegen ob Antwort möglich und ggf. antworten
Wer will wissen, wies unter Linux läuft? - Niemand!
War dein Beitrag hilfreich - Neeein!
Hi Habe mir nun überlegt die Kommunikation mit der NIC über TDI nicht in einen eigenene Treiber zu geben sondern meine Funktion in eine WDM Treiber zu geben und dort auch auf das TDI Interface zuzugreifen damit erspart ich mir die Performance für dir IRPs. Ist dies Möglich das ich in eine normalen WDM Treiber der selber keine HArdware steuert auf das TDI Interface zugreife? MFG Fresh
bin gespannt, wie du den TDI Treiber benutzen willst, ohne IRPs zu verwenden...
So ich schreibe gerade die all in one Version des Treiber also TDI und normale Logik alles in eine Treiber! Er funktioniert derzeit soweit recht gut nut habe ich ein ´komisches Phänomen drin! Er macht immer die selbe Arbeit nur teilweise braucht er 50% eines Core2Duos und teilweise 0%. Das Schwanken kommt immer Blockweise also mal ne minute 50% und dann mal ne minute 0% usw. Aber leider ändert es sich nicht so regelmässig! Hat jemand eine Idee was es sein könnte? DANKE MFG Fresh
Fresh wrote:
> Hat jemand eine Idee was es sein könnte?
Erwartest du darauf ensthaft eine Antwort?
>Hat jemand eine Idee was es sein könnte?
Hier handelt es sich zweifellos um eine Verzerrung im
Raum-Zeit-Kontinuum, vermutlich hervorgerufen durch die nahe Geburt
eines schwarzen Lochs.
Stell den Rechner mal in einen anderen Raum, oder lege dein
Arbeitszimmer mit Bleiplatten aus, dann müßte es gehen.
Falls das nicht hilft, wiege mal bitte deinen Computer und schreib mal
wie schwer er bei 0% und bei 50% Rechenlast jeweils ist. Das würde bei
der Fehlersuche helfen, falls ich mich mit der Verzerrungs-Theorie doch
irren sollte...
Hi Habe ein kleines Problem mit meinen Treiber. Er stürzt jedesmal beim entladen ab! Kann das daran liegen, das ich eine globle Variable habe auf die zwei Funktionen schreiben und lesen die in einen unterschiedlichen Dispatch level arbeiten? DANKE MFG fresh
@fresh Niemals globale Variablen verwenden, solche Dinge gehören gefälligst in die Device-Extension die du ja beim Erzeugen des Gerätes angelegt hast. Damit ist sichergestellt das wenn dein Treiber läuft du auch Zugriff darauf hast. Außerdem Zugriffe auf "globale" Variablen die also von mehreren Stellen schreibend/lesend zugegriffen werden kann immer gegeneinander sperren (Stichwort SpinLock) mfg T.Stütz
Hallo Danke für deine schnelle Antwort! Ich habe es nämlich so das meine UDP Empfangsfunktion die empfangenen Daten in einen Buffers schreiben soll und gleichzeitig daten aus einen anderen Buffer schicken soll! Dachte daher das ich einfach zwei globale Variablen mache die die zwei buffer darstellen. Das heist also ich muss dies in diese driver extension einbauen? MFG fresh
@fresh Ich spreche von DeviceObject->DeviceExtension (Typ DEVICE_EXTENSION) Das DeviceObject hast du ja vorher per IoCreateDevice() erzeugt, dazu hast du als Parameter das DriverObject übergeben. Eine "DriverExtension" gibt es meines Wissens nicht. Also: es gibt EIN DriverObject (repräsentiert quasi den Treiber) diesem DriverObject können mehrere DeviceObjects zugeordnet sein (jeweils per IoCreateDevice() erzeugt) dies sind also die Geräte die von diesem Treiber bedient werden (bei dir wären das mehrere Netzwerkkarten die alle von einem Treiber bedient werden).Jedes diese DeviceObjects kann zusätzliche Daten enthalten das ist dann die DeviceExtension (bei dir wäre das z.B. die der Netzwerkkarte zugeordnete IP-Adresse/MACAdresse) Du willst quasi zwei Puffer für Send/Empfang pro Netzwerkkarte haben => beide Puffer in die Device-Extension oder in der Device-Extension Zeiger definieren, die einen auf einen Speicherbereich der per ExAllocatePool Speicher angefordert (NonPaged!) wurde (NULL-Zeiger überwachen!!) Ich hoffe das macht es etwas klarer. mfG T.Stütz
Hallo Habe das mit den Buffern jetzt so gelöst und es funktioniert echt gut! Einzig stört mich ein wenig das ich bei 8000 eingehenden und 8000 ausgehenden Paketen mit jeweils 554Byte bereits eine CPU Last von fast 20% habe bei einen Core 2 Duo mit 2,2Ghz oder ist das fast normal! Die Pakete werden eigentlich nicht bearbeitet sonder derzeit nur die Addressen geändert und weitergeschickt! MFG Fresh
Dann sammle doch bis du eine größere Menge zusammen hast und versende die auf einmal zu dem anderen Treiber. Ein Timeout könnte dafür sorgen, dass die Daten auch rausgehen, wenn nicht die Maximalmenge innerhalb einer Zeitscheibe zusammenkommt, so bleibt nix hängen, sondern wird höchstens kurz verzögert.
Hi Ich beschäftige mich noch immer mit den Thema Treiberentwicklung und habe daher wieder eine Frage. Ich will das ein Thread so lange wartet bis ihn ein zweiter aufweckt! Habe ein Beispiel gefunden mit einen Semaphore das bei einen Wait aufruf decrementiert wird und bei eine Signal aufruf incrementiert! Ist das gane damit machbar!? DANKE MFG Gast
Habe davor vergessen zu erwähnen das der Thread alle 2ms aufgeweckt wird! MFG Gast
Ja, so mancht man das. Die 2 ms sollten kein Problem sein, wenn die Prozessorlast durch den Thread gering genug ist.
Hallo Habe nun ein Semaphore eingebaut und der thread wird auch perfekt aufgeweckt verrichtet seine arbeit und geht wieder in den wait state. Nur stürzt er immer ab wenn ich den Treiber entlade! habe mit softice festgestellt das er entweder beim signal oder im wait abstürzt und das obwohl noch nicht einmal die erste Zeile der Unloadfunktion aufgerufen wurde! Hat jemand vielleicht eine Tipp? MFG Gast
Ein Semaphore-Handle ist im Kernelmode ein Zeiger auf eine Datenstruktur. Wenn die Datenstruktur nicht mehr existiert und das Handle benutzt wird, krachts. Du mußt also dafür sorgen, daß alles sauber abgebaut wird, wenn du den Treiber entlädtst.
@ Uhu irgendwie werd ich das Gefühl nicht los, dass du so gar keine Ahnung hast und daher immer unkonkretes Zeug schreibst... Hier mal was konkretes... ...Ist zwar ein Event, aber das Prinzip ist bei der Semaphore das gleiche, wenns ums Beenden geht: Thread: while (1) { KeWaitForSingleObject(&m_evWait, Executive, KernelMode, FALSE, NULL); if ( m_WorkerRun == false ) { DPF(D_TERSE, ("StreamerThread: terminating")); return; } //... } Beenden geht so: m_WorkerRun = false; KeSetEvent(&m_evWait, 0, FALSE); ZwClose(m_hWorkerThread);
Hallo Also im Prinzip mach iches eh so! ich habe eine funktion die immer bei einen empfang einer UDP nachricht aufgerufen wird. diese Funktion gibt ein signal an das semaphor und startet dadruch einen thread der vorher auf das semaphor gewartet hat. Wenn ich nun den treiber entlade setzte ich eine globale variable auf 0 damit der udp teil nicht weiter macht. danach starte ich ein signal auf das semaphor damit der thread nochmals gestartet wird. im threat fragt er die globale variable ab und terminiert sich selber! Leider bekomme ich immer einen Page Fault (0Eh) Fehler! Weis jemand woran das liegen kann? MFG Gast
Hallo Habe jetzt statt einen semaphor ein Event genommen und es arbeitet echt super. Ausser das entladen des Treiber funktioniert nicht immer gelegentlich bekomme ich einen "Page Fault (9Eh)" Fehler. Wenn ich mir dann denn stack ansehe pasiert der Fehler meistens im wait des threads! Das entladen mache ich wie um vorigen post beschrieben! MFG Gast
Hi Habe noch eine Frage zur Treiberkommunikation! Ich habe ein Usermode Program welches Mittels DeviceioControl und CreateFile auf einen Treiber zugreift! Nun muss ich diesen Zugriff aus einen Treiber aus machen wobei der Createfile Befehl nicht geht! Benutze derzeit den Befehl IoGetDeviceObjectPointer zum aufbauen der Verbindung. Kann ich damit die selben Befehle wie mit DeviceIOControl übergeben!? MFG Gast
IRP_MJ_INTERNAL_DEVICE_CONTROL ist die Version von IRP_MJ_DEVICE_CONTROL, die zur Kommunikation zwischen Treibern benutzt wird. http://msdn.microsoft.com/en-us/library/ms806159.aspx
Hi Habe die Kommunikatin zum anderen Treiber erfolgreich implementieren können! Jetzt muss ich auch eine Funktion implementieren die an den anderen treiber einen irp schickt und daten zurück bekommt. Übergebe daher auch eine OutputBufferLength. Meine Frage ist nun wann ich die Daten abrufen kann und wie?! Bekomme ich die Daten sofort nach den IoCallDriver aufruf oder in der completionroutine? Und wo sind die Daten dann im IRP zu finden! Danke im vorhinein für die Antworten! MFG Gast
Natürlich in der Completionroutine. Mit dem I/O-complete signalisiert
der Zieltreiber, daß der IRP fertig bearbeitet ist, also z.B. Daten in
einen Puffer geschrieben wurden - oder daß irgenwas schief ging.
> Und wo sind die Daten dann im IRP zu finden!
Üblicherweise im Puffer, der übergeben wurde. Man kann aber natürlich
auch einen gemeinsamen Speicherbereich benutzen - im Kernelmode hat man
alle Freiheiten... Nur obs auch archtektonisch und sicherheitstechnisch
gut ist, steht auf einem anderen Blatt.
Hi Habe folgenden IRP Code:
1 | irpStack = IoGetNextIrpStackLocation(irp); |
2 | irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL; |
3 | irpStack->MinorFunction = 0; |
4 | irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_DRIVER_OUT; |
5 | irpStack->Parameters.DeviceIoControl.OutputBufferLength = sizeof(IOCTL_RX_OUT); |
6 | irpStack->Parameters.DeviceIoControl.InputBufferLength = sizeof(IOCTL_RX_IN); |
Nun würde ich gerne in der completion funktion die Daten aus den IOCTL_RX_OUT auslesen die mir der ander Treiber gegeben hat! Mein Versuch:
1 | IOCTL_RX_OUT data_tmp; |
2 | |
3 | data_tmp = (IOCTL_RX_OUT*)(irp->AssociatedIrp.SystemBuffer); |
Ist diese Vorgangsweise richtig!? DANKE MFG Gast
Hi Also die Kommunikation zwischen den Treibern geht! Aber leider habe ich oft einen Blue Screen wegen den IRQL. vorallem bei den memcpy befehlen! Habe auch schon RtlCopyMemory versucht was aber auch Fehler mit den IRQL bringt! Hat jemand einen vielleicht einen Tip oder sind memcpy Befehle im Kernel allgemein ein Problem? MFG Gast
Das deutet darauf hin, daß die Kopierroutine in einem Kontext gerufen wird, der keine Zugriffsrechte auf die Daten hat. Treiber laufen auf IRQL 0, während Anwenderprozesse auf IRQL 3 laufen. Die Kopierroutinen selbst laufen sehr zuverlässig - sind ja auch gut getestet...
HI Also mein memcpy Befehl arbeitet in einen Thread der zu einer Klasse gehört. Dieser Thread alloziiert sich selber speicher und in diesen Speicher will er einen Speicher welcher ebenfalls zur selben Klassse gehört kopieren. Kann das dann ein Problem mit den Kontext sein!? MFG Gast
Ja. Z.B. wenn der Thread durch ein Event zum Leben erwacht. Systemthreads sind nicht an einen Prozeßkontext gebunden. Wenn ein Th. im falschen Kontext aufwacht, dann darf er nur das, was in diesem Kontext möglich ist.
Hi Habe das Problem mit den memcpy lösen können hätte jetzt aber noch ne Frage zu den IRPs. Ich mache immer wenn ich Daten zum oder vom anderen Treiber schicken will ein neues IRP mit IoAllocateIrp. Nun ist mir aufgefallen das mein System Cache rasant ansteigt und ich vermute das der Rechner deswegen nach einer Zeit nicht mehr reagiert! ISt das Möglich?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.