Freigeben über


Behandeln von Streamanforderungsblöcken

Das Betriebssystem sendet alle E/A-Anforderungen auf dem Gerät an den Klassentreiber. Der Klassentreiber fordert wiederum hardwarespezifische Informationen vom Minitreiber an, indem er SRBs an den Minitreiber übergibt. Der Klassentreiber gibt den Vorgang an, den er im Command-Member des Streamanforderungsblocks anfordert.

Sowohl der Minidriver als Ganzes als auch jeder Stream innerhalb des Minidrivers können E/A-Anforderungen empfangen. Der Minidriver muss eine StrMiniReceiveDevicePacket-Routine bereitstellen, um geräteweite Anforderungen zu verarbeiten. Jeder Stream muss zwei Routinen unterstützen, um E/A-Anforderungen zu verarbeiten: eine für Datenanforderungen und eine für Steuerungsanforderungen. Der Klassentreiber ruft den Datenanforderungsrückruf StrMiniReceiveStreamDataPacket auf, um alle Lese- und Schreibanforderungen für einen Stream zu verarbeiten. Alle anderen Anforderungen für einen Stream werden an StrMiniReceiveStreamControlPacket übergeben.

Wenn der Klassentreiber die Synchronisierung für den Minitreiber verarbeitet, werden Streamanforderungen in die Warteschlange gestellt und einzeln an den Minitreiber gesendet. Der Klassentreiber verwaltet drei separate Warteschlangen – eine für Geräteanforderungen und jeweils eine für Streamdaten- und Steuerungsanforderungen. Der Minitreiber kann wie folgt signalisieren, dass er für eine neue Anforderung aus einer dieser Warteschlangen bereit ist:

Anforderungstyp -Routine zurückgegebener Wert NotificationType-Parameter der Routine

Geräteanforderung

StreamClassDeviceNotification

ReadyForNextDeviceRequest

Streamsteuerungsanforderung

StreamClassStreamNotification

ReadyForNextStreamControlRequest

Streamdatenanforderung

StreamClassStreamNotification

ReadyForNextStreamDataRequest

Wenn der Klassentreiber StrMiniReceiveXXXPacket aufruft, übergibt er den Streamanforderungsblock an den Minitreiber. Die Routine des Minitreibers hat nur Zugriff auf den Streamanforderungsblock, bis er dem Klassentreiber signalisiert, dass er die Anforderung abgeschlossen hat.

Wenn der Minitreiber die Verarbeitung einer Anforderung abgeschlossen hat, sollte er dem Klassentreiber signalisieren, dass er die Anforderung wie folgt abgeschlossen hat:

  1. Der Minidriver sollte die status der Anforderung im Feld Status des Streamanforderungsblocks festlegen.

  2. Der Minitreiber sollte durch Aufrufen von StreamClassDeviceNotification oder StreamClassStreamNotification signalisieren, dass er die Anforderung abgeschlossen hat. Um eine Geräteanforderung abzuschließen, ruft der Minidriver StreamClassDeviceNotification mit dem NotificationType-Parameter DeviceRequestComplete auf. Um eine Streamanforderung abzuschließen, ruft der Minidriver StreamClassStreamNotification mit dem NotificationType-Parameter StreamRequestComplete auf.

  3. Wenn der Klassentreiber die Synchronisierung verarbeitet und der Minitreiber dem Klassentreiber noch nicht signalisiert hat, dass er für eine weitere Anforderung in dieser Warteschlange bereit ist, sollte er dies jetzt tun.

Der Minidriver kann 2 und 3 kombinieren, indem StreamClassCompleteRequestAndMarkQueueReady aufgerufen wird.

Der Minitreiber verarbeitet Anforderungen asynchron, sodass der Klassentreiber möglicherweise eine Anforderung abbrechen oder timeouts muss. Für diese Zwecke muss der Minidriver ein StrMiniCancelPacket und eine StrMiniRequestTimeout-Routine bereitstellen. Der Klassentreiber ruft die jeweilige Minitreiberroutine auf, wenn er eine Anforderung abbricht oder ein Zeitüberschreitungsout durchführt.

Der Klassentreiber bricht eine Anforderung ab, wenn die zugrunde liegende E/A-Anforderung vom Betriebssystem abgebrochen wird. Der Klassentreiber gibt ein Timeout von Anforderungen ab, deren Verarbeitung zu lange dauert. Er dekrementiert einen Zähler der Anzahl von Sekunden, bis eine Anforderung im TimeoutCounter-Element des Streamanforderungsblocks timeoutoutout. Wenn der Minitreiber die Verarbeitung einer Anforderung für einen längeren Zeitraum zurückstellen muss, sollte er das TimeoutCounter-Element auf 0 (null) festlegen. Der Klassentreiber gibt dann kein Timeout für die Anforderung aus. Sobald der Minidriver die Verarbeitung der Anforderung wieder aufgenommen hat, sollte timeoutCounter so zurückgesetzt werden, dass er dem TimeoutOriginal-Member des Streamanforderungsblocks entspricht. Der Minitreiber kann TimeoutOriginal zurücksetzen, um die Zeitspanne zu ändern, bevor das Anforderungstimeout auftritt. Weitere Informationen finden Sie unter HW_STREAM_REQUEST_BLOCK .