IRP_MN_QUERY_DEVICE_RELATIONS

Der PnP-Manager sendet diese Anforderung, um bestimmte Beziehungen zwischen Geräten zu ermitteln. Die folgenden Treibertypen verarbeiten diese Anforderung:

  • Bustreiber müssen BusRelations-Anforderungen für ihren Adapter oder Controller (Bus-FDO) verarbeiten. Filtertreiber können BusRelations-Anforderungen verarbeiten.

  • Bustreiber müssen TargetDeviceRelation-Anforderungen für ihre untergeordneten Geräte (untergeordnete PDOs) verarbeiten.

  • Funktions- und Filtertreiber können RemovalRelations - und PowerRelations-Anforderungen verarbeiten.

  • Bustreiber können EjectionRelations-Anforderungen für ihre untergeordneten Geräte (untergeordnete PDOs) verarbeiten.

Wert

0x07

Hauptcode

IRP_MJ_PNP

Sendebedingungen

Der PnP-Manager sendet diese IRP, um Informationen zu Geräten mit einer Beziehung zum angegebenen Gerät zu sammeln.

Der PnP-Manager fragt die BusRelations (untergeordnete Geräte) eines Geräts ab, wenn das Gerät aufgezählt wird und zu anderen Zeiten, während das Gerät aktiv ist, z. B. wenn ein Treiber die IoInvalidateDeviceRelations-Routine aufruft , um anzugeben, dass ein untergeordnetes Gerät eingetroffen oder verlassen wurde.

Der PnP-Manager fragt die RemovalRelations eines Geräts ab, bevor er die Treiber eines Geräts entfernt. Der PnP-Manager fragt RemovalRelations und EjectionRelations ab, bevor ein Gerät ausgeworfen wird.

Der PnP-Manager fragt die TargetDeviceRelation eines Geräts ab, wenn sich ein Treiber oder eine Benutzermodusanwendung für eine PnP-Benachrichtigung über eine EventCategoryTargetDeviceChange auf dem Gerät registriert. Der PnP-Manager fragt das Gerät ab, das einem bestimmten Dateiobjekt zugeordnet ist. IRP_MN_QUERY_DEVICE_RELATIONS ist das einzige PnP-IRP, das über einen gültigen Dateiobjektparameter verfügt. Ein Treiber kann einen Gerätestapel für TargetDeviceRelation abfragen. Ein Treiber muss beim Senden seiner TargetDeviceRelation-Abfrage kein Dateiobjekt angeben.

Der PnP-Manager fragt die PowerRelations eines Geräts ab, wenn der Treiber für das Gerät IoInvalidateDeviceRelations aufruft , um anzugeben, dass sich der Satz von Geräten, mit denen dieses Gerät über eine implizite Energieverwaltungsbeziehung verfügt, geändert hat. PowerRelations-Anforderungen werden ab Windows 7 unterstützt.

Für BusRelations-, RemovalRelations-, EjectionRelations- und PowerRelations-Anforderungen sendet der PnP-Manager IRP_MN_QUERY_DEVICE_RELATIONS unter IRQL = PASSIVE_LEVEL im Kontext eines Systemthreads.

Bei TargetDeviceRelation-Anforderungen sendet der PnP-Manager diese IRP unter IRQL = PASSIVE_LEVEL in einem beliebigen Threadkontext.

Eingabeparameter

Der Parameters.QueryDeviceRelations.Type-Member der IO_STACK_LOCATION-Struktur gibt den Typ der abgefragten Beziehungen an. Mögliche Werte sind BusRelations, EjectionRelations, RemovalRelations, TargetDeviceRelation und PowerRelations.

Das FileObject-Element der aktuellen IO_STACK_LOCATION-Struktur zeigt nur auf ein gültiges Dateiobjekt, wenn Parameters.QueryDeviceRelations.Typeden Wert TargetDeviceRelation aufweist.

Ausgabeparameter

Wird im E/A-status-Block zurückgegeben.

E/A-Statusblock

Ein Treiber legt Irp-IoStatus.Status> auf STATUS_SUCCESS oder auf einen Fehler status wie z. B. STATUS_INSUFFICIENT_RESOURCES fest.

Bei Erfolg legt ein Treiber Irp-IoStatus.Information> auf einen PDEVICE_RELATIONS-Zeiger fest, der auf die angeforderten Beziehungsinformationen verweist. Die DEVICE_RELATIONS-Struktur ist wie folgt definiert:

typedef struct _DEVICE_RELATIONS {
  ULONG  Count;
  PDEVICE_OBJECT  Objects[1];  // variable length
} DEVICE_RELATIONS, *PDEVICE_RELATIONS;

Vorgang

Wenn ein Treiber als Reaktion auf diese IRP_MN_QUERY_DEVICE_RELATIONS Beziehungen zurückgibt, ordnet der Treiber eine DEVICE_RELATIONS Struktur aus dem ausgelagerten Speicher zu, die eine Anzahl und die entsprechende Anzahl von Geräteobjektzeigern enthält. Der PnP-Manager gibt die Struktur frei, wenn sie nicht mehr benötigt wird. Wenn ein Treiber eine DEVICE_RELATIONS Struktur ersetzt, die ein anderer Treiber zugewiesen hat, muss der Treiber die vorherige Struktur freigeben.

Ein Treiber muss auf die PDO jedes Geräts verweisen, das er in diesem IRP (ObReferenceObject) meldet. Der PnP-Manager entfernt den Verweis bei Bedarf.

Ein Funktions- oder Filtertreiber sollte bereit sein, diese IRP für ein Gerät jederzeit zu verarbeiten, nachdem die AddDevice-Routine für das Gerät abgeschlossen wurde. Bustreiber sollten darauf vorbereitet sein, eine Abfrage für BusRelations unmittelbar nach dem Aufzählen eines Geräts zu verarbeiten.

Die allgemeinen Regeln zur Behandlung Plug & Play Neben-IRPs finden Sie unter Plug & Play.

In den folgenden Unterabschnitten werden die spezifischen Aktionen für die Behandlung der verschiedenen Abfragen beschrieben.

BusRelations-Anforderung

Wenn der PnP-Manager die Busbeziehungen (untergeordnete Geräte) eines Adapters oder Controllers abfragt, muss der Bustreiber eine Liste von Zeigern auf die PDOs aller Geräte zurückgeben, die physisch im Bus vorhanden sind. Der Bustreiber meldet alle Geräte, unabhängig davon, ob sie gestartet wurden. Der Bustreiber muss möglicherweise sein Busgerät einschalten, um zu bestimmen, welche Untergeordneten vorhanden sind.

Warnung Ein Geräteobjekt kann nicht an eine Routine übergeben werden, die eine PDO als Argument akzeptiert, bis der PnP-Manager einen Geräteknoten (Devnode) für dieses Objekt erstellt. (Wenn der Treiber ein Geräteobjekt übergibt, überprüft das System die Fehlerüberprüfung mit der Fehlerüberprüfung 0xCA: PNP_DETECTED_FATAL_ERROR.) Der PnP-Manager erstellt den Devnode als Reaktion auf die IRP_MN_QUERY_DEVICE_RELATIONS-Anforderung . Der Treiber kann sicher davon ausgehen, dass der Devnode des PDO erstellt wurde, wenn er eine IRP_MN_QUERY_RESOURCE_REQUIREMENTS-Anforderung empfängt.

Der Bustreiber, der auf diese IRP antwortet, ist der Funktionstreiber für den Busadapter oder Controller, nicht der übergeordnete Bustreiber für den Bus, mit dem der Adapter oder Controller verbunden ist. Funktionstreiber für Nicht-Bus-Geräte verarbeiten diese Abfrage nicht. Solche Treiber übergeben den IRP einfach an den nächstniedringen Treiber. (Siehe folgende Abbildung.) Filtertreiber verarbeiten diese Abfrage in der Regel nicht.

Unter Windows Vista und höheren Betriebssystemen wird empfohlen, dass Treiber immer die IRP_MN_QUERY_DEVICE_RELATIONS IRP verwenden und die Verarbeitung später abschließen. Diese Reihenfolge ermöglicht es dem System, Busbeziehungsabfragen asynchron zu verarbeiten. (Auf Betriebssystemen vor Windows Vista können Treiber sicher STATUS_PENDING aus ihren Dispatchroutinen zurückgeben, aber der PnP-Manager überschneidet die Busbeziehungsabfrage nicht mit anderen Vorgängen.)

Das folgende Diagramm zeigt, wie Treiber eine Abfrage für Busbeziehungen verarbeiten.

Diagramm zur Veranschaulichung von Treibern, die eine Abfrage für Busbeziehungen verarbeiten.

Im in der Abbildung gezeigten Beispiel sendet der PnP-Manager eine IRP_MN_QUERY_DEVICE_RELATIONS für BusRelations an die Treiber für das USB-Hubgerät. Der PnP-Manager fordert eine Liste der untergeordneten Elemente des Hubgeräts an.

  1. Wie bei allen PnP-IRPs sendet der PnP-Manager den IRP an den obersten Treiber im Gerätestapel für das Gerät.

  2. Ein optionaler Filtertreiber kann der oberste Treiber im Stapel sein. Ein Filtertreiber verarbeitet diese IRP in der Regel nicht. sie übergibt den IRP im Stapel. Ein Filtertreiber kann diese IRP verarbeiten, z. B. wenn der Treiber ein nicht aufzählbares Gerät im Bus verfügbar macht.

  3. Der USB-Hubbustreiber verarbeitet die IRP.

    Der USB-Hubbustreiber:

    • Erstellt eine PDO für alle untergeordneten Geräte, die noch keines besitzen.

    • Markiert die PDO inaktiv für alle Geräte, die nicht mehr im Bus vorhanden sind. Der Bustreiber löscht solche PDOs nicht.Weitere Informationen dazu, wann die PDOs gelöscht werden sollen, finden Sie unter Entfernen eines Geräts.

    • Meldet alle untergeordneten Geräte, die im Bus vorhanden sind.

      Für jedes untergeordnete Gerät verweist der Bustreiber auf das PDO und legt einen Zeiger auf die PDO in der DEVICE_RELATIONS-Struktur.

      In diesem Beispiel gibt es zwei PDOs: eines für das Joystick-Gerät und eines für das Tastaturgerät.

      Der Bustreiber sollte überprüfen, ob bereits ein anderer Treiber eine DEVICE_RELATIONS-Struktur für dieses IRP erstellt hat. Wenn ja, muss der Bustreiber den vorhandenen Informationen hinzufügen.

      Wenn im Bus kein untergeordnetes Gerät vorhanden ist, legt der Treiber die Anzahl in der DEVICE_RELATIONS-Struktur auf Null fest und gibt den Erfolg zurück.

    • Legt die entsprechenden Werte im E/A-status-Block fest und übergibt den IRP an den nächstniedreren Treiber. Der Bustreiber für den Adapter oder Controller schließt die IRP nicht ab.

  4. Ein optionaler niedrigerer Filter, sofern vorhanden, behandelt diese IRP in der Regel nicht. Ein solcher Filtertreiber übergibt den IRP im Stapel nach unten. Wenn ein Treiber mit niedrigerem Filter diese IRP verarbeitet, kann er der Liste der untergeordneten Geräte PDO(s) hinzufügen, darf jedoch keine pdOs löschen, die von anderen Treibern erstellt wurden.

  5. Der übergeordnete Bustreiber verarbeitet diese IRP nicht, es sei denn, er ist der einzige Treiber im Gerätestapel (das Gerät befindet sich im Rohmodus). Wie bei allen PnP-IRPs schließt der übergeordnete Bustreiber das IRP mit IoCompleteRequest ab.

    Wenn ein oder mehrere Busfiltertreiber im Gerätestapel vorhanden sind, können solche Treiber den IRP auf dem Weg nach unten zum Bustreiber und/oder auf dem Weg des IRP nach oben im Gerätestapel verarbeiten (wenn IoCompletion-Routinen vorhanden sind). Gemäß den PnP-IRP-Regeln kann ein solcher Treiber dem IRP pdOs auf dem Weg nach unten im Stapel hinzufügen und/oder die Beziehungsliste auf dem Weg nach oben im Stapel des IRP ändern (in IoCompletion-Routinen ).

EjectionRelations-Anforderung

Ein Treiber gibt Zeiger auf PDOs aller Geräte zurück, die beim Auswerfen des angegebenen Geräts physisch aus dem System entfernt werden können. Melden Sie nicht die PDOs der untergeordneten Geräte. Der PnP-Manager fordert immer an, dass untergeordnete Geräte vor dem übergeordneten Gerät entfernt werden.

Der PnP-Manager sendet eine IRP_MN_EJECT IRP an ein Gerät, das ausgeworfen wird. Der Treiber für ein solches Gerät erhält ebenfalls eine Entfernungs-IRP. Die Auswurfbeziehungen des Geräts erhalten eine IRP_MN_REMOVE_DEVICE IRP (keine IRP_MN_EJECT IRP).

Nur ein übergeordneter Bustreiber kann auf eine EjectionRelations-Abfrage für eines seiner untergeordneten Geräte reagieren. Funktions- und Filtertreiber müssen sie an den nächstniedren Treiber im Gerätestapel übergeben. Wenn ein Bustreiber diesen IRP als Funktionstreiber für seinen Adapter oder Controller empfängt, führt der Bustreiber die Aufgaben eines Funktionstreibers aus und muss den IRP an den nächstniedrigsten Treiber übergeben.

PowerRelations-Anforderung

Ab Windows 7 ermöglicht die PowerRelations-Abfrage einem Treiber, eine Energieverwaltungsbeziehung außerhalb der herkömmlichen Beziehung zwischen einem übergeordneten Bus, der die PnP-Enumeration unterstützt, und einem aufgezählten untergeordneten Gerät auf dem Bus anzugeben. Wenn beispielsweise ein Bustreiber kein untergeordnetes Gerät im Bus auflisten kann oder ein Gerät ein untergeordnetes Gerät von mehr als einem Bus ist, kann die PowerRelations-Abfrage die Leistungsbeziehungen des untergeordneten Geräts mit dem Bus oder den Bussen beschreiben.

Der PnP-Manager stellt eine PowerRelations-Abfrage für ein Gerät aus, wenn der Treiber für das Gerät die IoInvalidateDeviceRelations-Routine aufruft und einen Type-Parameterwert von PowerRelations angibt.

Als Antwort auf diese Abfrage stellt der Treiber für das Zielgerät (d. h. das Gerät, das das Ziel für die Abfrage ist) eine DEVICE_RELATIONS-Struktur bereit, die Zeiger auf die PDOs aller anderen Geräte enthält, die vom Energie-Manager aktiviert werden müssen, bevor das Zielgerät aktiviert wird. Umgekehrt müssen diese anderen Geräte erst ausgeschaltet werden, nachdem das Zielgerät ausgeschaltet wurde. Der Power Manager verwendet die Informationen aus der Abfrage, um sicherzustellen, dass diese Geräte in der richtigen Reihenfolge ein- und ausgeschaltet werden.

Diese Bestellgarantie gilt nur für globale Systemzustandsübergänge im Ruhezustand, einschließlich Übergängen zu und von den Systemzuständen S1, S2, S3 (Ruhezustand), S4 (Ruhezustand) und S5 (Herunterfahren). Die PowerRelations-Bestellgarantie gilt nicht für Dx-Gerätestromzustandsübergänge, während sich das System im Systemzustand S0 (ausgeführt) befindet, mit Ausnahme von DFx-Übergängen (Direct Runtime Power Management).

Wenn sich das Zielgerät im Gerätepfad für eine spezielle Datei befindet (z. B. die Auslagerungsdatei, die Ruhezustandsdatei oder die Absturzabbilddatei), muss der Treiber für das Zielgerät einen zusätzlichen Schritt ausführen, wenn es einen IRP_MN_DEVICE_USAGE_NOTIFICATION IRP verarbeitet, in dem InPathTRUE ist. Dieser Treiber muss sicherstellen, dass die Geräte, deren PDOs für die PowerRelations-Abfrage bereitgestellt werden, auch unterstützen können, sich im Gerätepfad für die spezielle Datei zu befinden. Um diese Unterstützung zu bestätigen, muss der Treiber für das Zielgerät zuerst die IRP_MN_DEVICE_USAGE_NOTIFICATION IRP an jedes dieser Geräte senden, und dieses IRP muss dieselbe UsageNotification.Type wie das Zielgerät angeben. Nur wenn alle Geräte, die diese IRP erhalten, die IRP mit einem erfolgreichen status Code abschließen, kann der Treiber für das Zielgerät seine IRP_MN_DEVICE_USAGE_NOTIFICATION IRP erfolgreich abschließen. Andernfalls muss dieser Treiber diese IRP mit einem Fehler status Code abschließen.

Wenn derselbe Treiber eine IRP_MN_DEVICE_USAGE_NOTIFICATION IRP verarbeitet, für die InPathFALSE ist, muss der Treiber die IRP_MN_DEVICE_USAGE_NOTIFICATION IRP an denselben Satz abhängiger Geräte senden wie für den Fall, in dem InPathTRUE ist. Der Treiber sollte diese IRP jedoch nie mit einem Fehler status Code abschließen, wenn InPathFALSE ist.

Der Treiber, der auf die PowerRelations-Abfrage antwortet, sollte für Zielgeräteänderungsbenachrichtigungen auf allen Geräten registriert werden, deren PDOs für die PowerRelations-Abfrage bereitgestellt werden. Um sich für diese Benachrichtigungen zu registrieren, kann der Treiber die IoRegisterPlugPlayNotification-Routine aufrufen und einen EventCategory-Parameterwert für EventCategoryTargetDeviceChange angeben.

RemovalRelations-Anforderung

Ein Treiber gibt Zeiger auf PDOs aller Geräte zurück, deren Treiber entfernt werden müssen, wenn die Treiber für das angegebene Gerät entfernt werden. Melden Sie die PDOs der untergeordneten Geräte des Geräts nicht. Der PnP-Manager fordert bereits die Entfernung untergeordneter Geräte an, bevor ein Gerät entfernt wird.

Die Reihenfolge, in der Entfernungsbeziehungen entfernt werden, ist nicht definiert.

Jeder Treiber im Gerätestapel kann diese Art von Beziehungsabfrage verarbeiten. Ein Funktions- oder Filtertreiber verarbeitet die IRP, bevor sie an den nächstniedrig nächstniedrig gesetzten Treiber übergeben wird. Ein Bustreiber verarbeitet die IRP und schließt sie dann ab.

TargetDeviceRelation-Anforderung

Mit der TargetDeviceRelation-Abfrage kann der PnP-Manager einen Nicht-PnP-Gerätestapel für den PDO im PnP-Gerätestapel abfragen, der die Hardware steuert.

Im Allgemeinen leiten Treiber die IRP_MN_QUERY_DEVICE_RELATIONS IRP nach unten weiter, bis der IRP den unteren Rand eines bestimmten Gerätestapels erreicht. Ein Treiber am unteren Rand eines Nicht-PnP-Stapels leitet den IRP dann weiter oder stellt ihn erneut an den entsprechenden PnP-Stapel aus. Beispielsweise kann der PnP-Manager eine TargetDeviceRelation-Abfrage an das Geräteobjekt am oberen Rand des Dateisystemstapels senden, bei dem es sich um einen Nicht-PnP-Stapel handelt. Jedes Geräteobjekt im Dateisystemstapel übergibt die Abfrage an das darunter stehende Geräteobjekt, bis die Abfrage das Geräteobjekt am unteren Rand des Stapels erreicht hat. Das niedrigste Geräteobjekt im Stapel würde die TargetDeviceRelation-Abfrage an das Geräteobjekt oben im PnP-Speichervolume-Stapel weiterleiten oder erneut ausstellen, und dann wird die Abfrage an die PDO am unteren Rand des Speichervolume-Stapels übergeben.

Die folgende Liste fasst die Situationen zusammen, in denen Sie sicher einen Zeiger auf die PDO am unteren Rand eines PnP-Gerätestapels abrufen können:

  • Geräteobjekt in einem PnP

    Ein Geräteobjekt, das sich in einem PnP-Gerätestapel befindet, informiert sich über die PDO des Stapels, wenn die AddDevice-Routine für das Gerät aufgerufen wird. Der Treiber kann den Zeiger auf die PDO sicher zwischenspeichern, wenn die Verwendung des Zeigers ordnungsgemäß mit eingehenden IRP_MN_REMOVE_DEVICE Nachrichten synchronisiert wird, indem die Remove-Sperrroutinen verwendet werden.

  • Geräteobjekt in einem Nicht-PnP-Stapel, nicht am unteren Rand des Stapels

    Für ein Geräteobjekt, das sich nicht am unteren Rand eines Nicht-PnP-Stapels befindet, kann ein Treiber eine TargetDeviceRelation-Abfrage senden, um einen Zeiger auf die PDO am unteren Rand des entsprechenden PnP-Gerätestapels abzurufen.

  • Dateiobjekt für das Gerät

    Bei einem Dateiobjekt für das Gerät kann ein Treiber IoGetRelatedDeviceObject aufrufen, um das Geräteobjekt abzurufen, und dann die Anweisungen im vorherigen Listenelement befolgen.

  • Behandeln des Geräteobjekts

    Bei einem Handle für das Geräteobjekt kann ein Treiber ObReferenceObjectByHandle aufrufen, um das Dateiobjekt für das Gerät abzurufen, und dann die Anweisungen im vorherigen Listenelement befolgen.

Ein übergeordneter Bustreiber muss eine TargetDeviceRelation-Beziehungsabfrage für seine untergeordneten Geräte verarbeiten. Der Bustreiber verweist mit ObReferenceObject auf die PDO des untergeordneten Geräts und gibt einen Zeiger auf die PDO in der DEVICE_RELATIONS-Struktur zurück. Es gibt nur einen pDO-Zeiger in der Struktur für diesen Beziehungstyp. Der PnP-Manager entfernt den Verweis auf die PDO, wenn der Treiber oder die Anwendung die Registrierung für Benachrichtigungen auf dem Gerät auf hebt.

Nur ein übergeordneter Bustreiber antwortet auf eine TargetDeviceRelation-Abfrage . Funktions- und Filtertreiber müssen sie an den nächstniedringen Treiber im Gerätestapel übergeben. Wenn ein Bustreiber diese IRP als Funktionstreiber für seinen Adapter oder Controller empfängt, führt der Bustreiber die Aufgaben eines Funktionstreibers aus und muss den IRP an den nächstniedrenden Treiber übergeben.

Wenn sich ein Treiber nicht in einem PDO-basierten Stapel befindet, sendet der Treiber eine neue Zielgerät-Beziehungsabfrage an das Geräteobjekt, das dem Dateihandle zugeordnet ist, für das der Treiber E/A ausführt.

Senden dieses IRP

Treiber dürfen keine IRP_MN_QUERY_DEVICE_RELATIONS senden, um BusRelations anzufordern. Treiber sind nicht daran beschränkt, diese IRP für RemovalRelations oder EjectionRelations zu senden, aber es ist nicht wahrscheinlich, dass ein Treiber dies tut.

Treiber können einen Gerätestapel für TargetDeviceRelation abfragen. Informationen zum Senden von IRPs finden Sie unter Behandeln von IRPs . Die folgenden Schritte gelten speziell für diese IRP:

  • Legen Sie die Werte am nächsten E/A-Stapelspeicherort des IRP fest: Legen Sie MajorFunction auf IRP_MJ_PNP fest, legen Sie MinorFunction auf IRP_MN_QUERY_DEVICE_RELATIONS fest, legen Sie Parameters.QueryDeviceRelations.Type auf TargetDeviceRelation fest, und legen Sie Irp-FileObject> auf ein gültiges Dateiobjekt fest.

  • Initialisieren Sie IoStatus.Status , um STATUS_NOT_SUPPORTED.

Wenn ein Treiber diese IRP gesendet hat, um die PDO als Reaktion auf eine IRP_MN_QUERY_DEVICE_RELATIONS für TargetDeviceRelation zu melden, die der Treiber empfangen hat, meldet der Treiber die PDO und gibt die zurückgegebene Beziehungsstruktur frei, wenn die IRP abgeschlossen ist. Wenn ein Treiber diese IRP aus einem anderen Grund initiiert hat, gibt der Treiber die Beziehungsstruktur frei, wenn das IRP abgeschlossen wird, und leitet die PDO ab, wenn sie nicht mehr benötigt wird.

Anforderungen

Header

Wdm.h (einschließlich Wdm.h, Ntddk.h oder Ntifs.h)

Weitere Informationen

AddDevice

IoCompleteRequest

IoGetRelatedDeviceObject

IoInvalidateDeviceRelations

IoRegisterPlugPlayNotification

IRP_MJ_PNP

IRP_MN_DEVICE_USAGE_NOTIFICATION

IRP_MN_EJECT

IRP_MN_QUERY_RESOURCE_REQUIREMENTS

IRP_MN_REMOVE_DEVICE

IO_STACK_LOCATION

ObReferenceObject

ObReferenceObjectByHandle