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
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.
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
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
>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
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
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
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?