関数またはフィルター ドライバーの AddDevice ルーチンは、次の手順を実行する必要があります。
IoCreateDevice を呼び出して、追加するデバイスの機能デバイス オブジェクトまたはフィルター デバイス オブジェクト (FDO またはフィルター DO) を作成します。
PnP マネージャーのセキュリティをバイパスするため、デバイス オブジェクトの DeviceName を指定しないでください。 ユーザー モード コンポーネントにデバイスへのシンボリック リンクが必要な場合は、デバイス インターフェイスを登録します (次の手順を参照)。 カーネル モード コンポーネントにレガシ デバイス名が必要な場合、ドライバーはデバイス オブジェクトに名前を付ける必要がありますが、名前付けはお勧めしません。
DeviceCharacteristics パラメーターにFILE_DEVICE_SECURE_OPENを含めます。 この特性により、I/O マネージャーは、すべてのオープン要求に対してデバイスオブジェクトに対してセキュリティチェックを実行するように指示されます。これには、相対オープンと末尾ファイル名オープンが含まれます。
[省略可能]デバイスへのシンボリック リンクを 1 つ以上作成します。
IoRegisterDeviceInterface を呼び出してデバイス機能を登録し、アプリケーションまたはシステム コンポーネントがデバイスを開くために使用できるシンボリック リンクを作成します。 ドライバーは、IRP_MN_START_DEVICE要求を処理するときに IoSetDeviceInterfaceState を呼び出すことによって、インターフェイスを有効にする必要があります。 詳細については、「 デバイス インターフェイス クラス」を参照してください。
デバイスの PDO へのポインターをデバイス拡張機能に格納します。
PnP マネージャーは、 AddDevice に PhysicalDeviceObject パラメーターとして PDO へのポインターを提供 します。 ドライバーは、 IoGetDeviceProperty などのルーチンの呼び出しで PDO ポインターを使用します。
デバイス拡張機能でフラグを定義して、デバイスの特定の PnP 状態 (デバイスの一時停止、削除、突然削除など) を追跡します。
たとえば、デバイスが一時停止状態の間に受信 IRP を保持する必要があることを示すフラグを 1 つ定義します。 ドライバーに IRP をキューに格納するためのメカニズムがまだない場合は、IRP を保持するためのキューを作成します。 詳細については、IRP のキューイングとデキューイングをご参照ください。
また、デバイス拡張機能 にIO_REMOVE_LOCK 構造体を割り当て、 IoInitializeRemoveLock を呼び出してこの構造体を初期化します。 詳細については、「ロックの削除を使用する」を参照してください。
デバイス オブジェクトのDO_BUFFERED_IOまたはDO_DIRECT_IO フラグ ビットを設定して、デバイス スタックに送信される I/O 要求に I/O マネージャーが使用するバッファリングの種類を指定します。 最上位レベルのドライバーを除き、上位レベルのドライバーまたはこのメンバーは、スタック内の次の下位ドライバーと同じ値を持ちます。 詳細については、「デバイス オブジェクトの初期化」を参照してください。
必要に応じて、電源管理のDO_POWER_INRUSHまたはDO_POWER_PAGABLE フラグを設定します。 ページング可能なドライバーは、DO_POWER_PAGABLE フラグを設定する必要があります。 デバイス オブジェクト フラグは、通常、デバイスの PDO を作成するときにバス ドライバーによって設定されます。 ただし、上位レベルのドライバーは、場合によっては、FDO またはフィルターの DO を作成するときに、 AddDevice ルーチンでこれらのフラグの値を変更する必要があります。 詳細については、「 Power Management のデバイス オブジェクト フラグの設定 」を参照してください。
イベント、スピン ロック、その他のオブジェクトなど、ドライバーがこのデバイスの管理に使用するその他のソフトウェア リソースを作成または初期化します。 (I/O ポートなどのハードウェア リソースは、 後でIRP_MN_START_DEVICE 要求に応答して構成されます)。
AddDevice ルーチンは IRQL = PASSIVE_LEVEL のシステム スレッド コンテキストで実行されるため、初期化時に排他的に使用するために ExAllocatePoolWithTag で割り当てられたメモリは、ドライバーがシステム ページ ファイルを保持するデバイスを制御しない限り、ページ プールから取得できます。 このようなメモリ割り当ては、AddDevice が制御を返す前に ExFreePool で解放する必要があります。
デバイス オブジェクトをデバイス スタックにアタッチします (IoAttachDeviceToDeviceStack)。
TargetDevice パラメーターで、デバイスの PDO へのポインターを指定します。
IoAttachDeviceToDeviceStack によって返されるポインターを格納します。 デバイスの次の下位ドライバーのデバイス オブジェクトを指すこのポインターは、デバイス スタックに IRP を渡すときに IoCallDriver と PoCallDriver に必要なパラメーターです。
FDO のDO_DEVICE_INITIALIZING フラグをクリアするか、次のようなステートメントを使用して DO をフィルター処理します。
FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;デバイスの PnP IRP ( IRP_MN_QUERY_RESOURCE_REQUIREMENTS や IRP_MN_START_DEVICEなど) を処理するように準備する必要があります。
ドライバーは、PnP マネージャーによってデバイスに割り当てられているハードウェア リソースの一覧を含む IRP_MN_START_DEVICE を受け取るまで、デバイスの制御を開始しないでください。