次の方法で共有


オブジェクトのライフ サイクル

このトピックでは、オブジェクトの "ライフ サイクル" について説明します。つまり、オブジェクトマネージャーがオブジェクトを参照および追跡する方法について説明します。 このトピックでは、オブジェクトを一時的または永続的にする方法についても説明します。

オブジェクト参照数

オブジェクト マネージャーは、オブジェクトへの参照の数を保持します。 オブジェクトが作成されると、オブジェクト マネージャーはオブジェクトの参照カウントを 1 に設定します。 そのカウンターが 0 になると、オブジェクトは解放されます。

ドライバーは、オブジェクト マネージャーが操作するすべてのオブジェクトの正確な参照数を持っていることを確認する必要があります。 途中で解放されたオブジェクトによって、システムがクラッシュする可能性があります。 参照カウントが誤って高いために、そのオブジェクトは解放されません。

オブジェクトは、ハンドルまたはポインターによって参照できます。 オブジェクト マネージャーは、参照カウントに加えて、オブジェクトに対して開いているハンドルの数を保持します。 ハンドルを開く各ルーチンは、オブジェクト参照カウントとオブジェクト ハンドル数の両方を 1 ずつ増やします。 このようなルーチンの各呼び出しは、 ZwClose への対応する呼び出しと一致する必要があります。 詳細については、「オブジェクト ハンドル」を参照してください。

カーネル モードでは、オブジェクトをオブジェクトへのポインターで参照できます。 IoGetAttachedDeviceReference などのオブジェクトへのポインターを返すルーチンは、参照カウントを 1 ずつ増やします。 ポインターを使用してドライバーが完了したら、 ObDereferenceObject を呼び出して参照カウントを 1 ずつ減らす必要があります。

次のルーチンはすべて、オブジェクトの参照カウントを 1 つ増やします。

ExCreateCallback

IoGetAttachedDeviceReference

IoGetDeviceObjectPointer

IoWMIOpenBlock

ObReferenceObject

ObReferenceObjectByHandle

ObReferenceObjectByPointer

上記のルーチンのいずれかに対して行われる各呼び出しは、 ObDereferenceObject への対応する呼び出しと一致する必要があります。

ObReferenceObject ルーチンと ObReferenceObjectByPointer ルーチンは、ドライバーが既知のオブジェクト ポインターの参照数を 1 つ増やすことができるように提供されます。 ObReferenceObject は、参照カウントを増やすだけです。 ObReferenceObjectByPointer は、参照カウントを増やす前にアクセス チェックを行います。

ObReferenceObjectByHandle ルーチンは、オブジェクト ハンドルを受け取り、基になるオブジェクトへのポインターを提供します。 参照カウントも 1 つ増やします。

一時オブジェクトと永続的オブジェクト

ほとんどのオブジェクトは 一時的なものです。これらは使用中である限り存在し、オブジェクト マネージャーによって解放されます。 永続的なオブジェクトを作成できます。 オブジェクトが永続的な場合、オブジェクト マネージャー自体はオブジェクトへの参照を保持します。 したがって、その参照カウントは 0 より大きいままであり、オブジェクトが使用されなくなった場合は解放されません。

一時オブジェクトは、ハンドル数が 0 以外の場合にのみ、名前でアクセスできます。 ハンドル数が 0 に減ると、オブジェクトマネージャーの名前空間からオブジェクトの名前が削除されます。 このようなオブジェクトは、参照カウントが 0 より大きい限り、ポインターによって引き続きアクセスできます。 永続的なオブジェクトは、存在する限り、名前でアクセスできます。

オブジェクトの作成時に、オブジェクトの OBJECT_ATTRIBUTES構造で OBJ_PERMANENT属性を指定することで、オブジェクトを永続的にすることができます。 詳細については、「 InitializeObjectAttributes」を参照してください。

永続的なオブジェクトを一時的にするには、 ZwMakeTemporaryObject ルーチンを使用します 。 このルーチンにより、オブジェクトは使用されなくなった後に自動的に削除されます。 (オブジェクトに開いているハンドルがない場合、オブジェクトの名前はオブジェクト マネージャーの名前空間から直ちに削除されます。オブジェクト自体は、参照カウントが 0 になるまで保持されます)。