記憶域クラス ドライバーでのマウント マネージャー要求のサポート
システム提供のマウント・マネージャーは、ボリューム名の管理を担当します。 ボリュームごとに、ボリュームがシステムから削除された後でも、ボリュームで一意で永続的に識別される名前が格納されます。 また、ドライブ文字などの永続性の低い名前も管理します。再起動後も保持されますが、ボリュームがシステムに追加またはシステムから削除されると割り当てが変更される可能性があります。
マウント マネージャーは、ボリュームのデバイス オブジェクトへのシンボリック リンクを作成することによって、システム内の各ボリュームに固有のインターフェースを提供します。 シンボリック リンク自体と、対象のデバイス オブジェクトはシステムの再起動時に保持されないため、マウント マネージャーはレジストリ内の永続的な名前データベースにシンボリック リンクの名前を保持します。
このシンボリック リンク名は、 一意のボリューム名と呼ばれます。 従来のボリューム ラベルと同様に、システムの再起動時にも保持されます。 ドライブ文字と同様に、ボリューム ラベルとは異なり、この名前は一意です。 一意のボリューム名の形式は次のとおりです。GUID は、ボリュームを識別するグローバル一意識別子です。
"\??\Volume{GUID}\
マウント マネージャーの永続的な名前データベースは、レジストリの SYSTEM ハイブ (HKLM/SYSTEM/MountedDevices) の MountedDevices レジストリ キーにあります。 マウント マネージャーは、一意のボリューム名に加えて、 マウント ポイント 名も永続的な名前データベースに格納します。 マウント ポイント名は、マウントされたボリュームのファイル システムのルート ディレクトリとして機能する Win32 スタイルのパス名とドライブ文字の 2 つのカテゴリにさらに分割できます。
データベース内の各永続的なシンボリック リンク名は、 一意の IDを伴う MountedDevices キーの下のレジストリ値の名前として表示されます。 一意の ID は、ボリュームの別の一意識別子です (一意のボリューム名とは異なります)。 これは、同じボリュームを参照する永続的なシンボリック リンク名が多数存在する可能性がある名前を識別するのに役立ちます。
たとえば、 一意のボリューム名が **"\\?\Volume{**7603f260-142a-11d4-ac67-806d6172696f の単一ボリューム }\" には、ドライブ文字 "\DosDevices\D:" と 2 つのマウント ポイント "\DosDevices\C:\mymount" と "\DosDevices\E:\FilesysD\mnt" があります。 この組み合わせにより、マウント・マネージャーの永続シンボリック・リンク名データベースに 4 つの項目が生成されます。1 つは一意のボリューム名、1 つはドライブ文字用、2 つはマウント・ポイント名です。 4 つのエントリはすべて同じ一意の ID を共有します。 したがって、MountedDevices レジストリ キーを表示しているユーザーは、4 つの永続的な名前がすべて同じボリュームを指していることを検出できます。
次のスクリーンショットは、MountedDevices レジストリ キーに永続的な名前がどのように表示されるかを示しています。
マウント マネージャーは、プラグ アンド プレイ デバイス インターフェイス通知メカニズムに依存して、ボリュームの到着と削除を警告します。 そのため、すべてのクライアント (つまり、すべてのボリューム ドライバー、通常はクラス ドライバー) は、 IoRegisterDeviceInterface を呼び出して、MOUNTDEV_MOUNTED_DEVICE_GUID インターフェイス クラスにインターフェイスを作成して、管理するボリュームのシステムへの到着をマウント マネージャーに通知する必要があります。 MOUNTDEV_MOUNTED_DEVICE_GUID インターフェイス クラス GUID は mountmgr.h で定義されています。
ボリューム インターフェイスの到着に関するプラグ アンド プレイ通知を受け取ると、マウント マネージャーはクライアントに次の 3 つのデバイス 制御 IRP を送信します。
- IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
- IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
- IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
これら 3 つの IOCTL に応答して、クライアントは、システム オブジェクト ツリーの Device ディレクトリ ("\Device\HarddiskVolume1" など) にあるボリュームの非永続的なデバイス オブジェクト名 (またはターゲット名)、一意のボリューム ID、およびボリュームの推奨される永続的なシンボリック リンク名をそれぞれ返す必要があります。 クライアントはIOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAMEを無視することもできますが、IOCTL_MOUNTDEV_QUERY_DEVICE_NAMEまたはIOCTL_MOUNTDEV_QUERY_UNIQUE_IDを受信したときに一意のボリューム ID を指定する必要があります。 マウント マネージャーは、一意のボリューム ID を提供するためにクライアントに完全に依存します。 クライアントが提供しない場合、マウント マネージャーはドライブ文字などのマウント ポイントをボリュームに割り当てることができません。
クライアントがボリュームの到着をマウント マネージャーに警告するが、クエリを実行したときにボリュームの一意の ID を指定できない場合、ボリュームは マウントされていないデバイス リスト に配置されます。 このような状況が発生した場合、クライアントはマウント マネージャーに IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES IOCTL を送信して、マウント マネージャーがマウントされていないデバイス リストを再スキャンするように要求し、その一覧のクライアントに対して、それぞれのボリュームの一意の ID を照会することをもう一度試みることができます。
マウント マネージャーが新しく導入されたボリュームの一意のボリューム ID を受け取った後:
- そのデータベースで、その一意の ID に割り当てられているすべての永続的な名前が検索されます。
- 永続シンボリック・リンク名ごとにボリュームへのシンボリック・リンクが作成されます。
マウント・マネージャーは、ボリュームが行き切れたことを検出すると、マウント・マネージャーのデータベース内の対応するシンボリック・リンク名を削除せずに、デバイス・オブジェクトを指すシンボリック・リンクを削除します。
マウント マネージャー クライアントが永続的なシンボリック名を作成する方法については、 IOCTL_MOUNTMGR_CREATE_POINT を参照してください。
マウント マネージャー クライアントによって送信される I/O コントロール コード
マウント マネージャーは、マウント マネージャーのクライアントがボリュームの永続的な名前を設定、クエリ、および削除できるようにするインターフェイスを発行します。 このインターフェイスにアクセスするために、クライアントは Mountmgr.h で定義されているオブジェクト名MOUNTMGR_DEVICE_NAMEを使用して、マウント マネージャーのデバイス オブジェクトへのポインターを取得できます。 次に例を示します。
// Obtain a pointer to the mount manager device object &
// use it to send any of the I/O Control codes in this
// section to the mount manager.
RtlInitUnicodeString(&name, MOUNTMGR_DEVICE_NAME);
status = IoGetDeviceObjectPointer(&name,
FILE_READ_ATTRIBUTES,
&fileObject, &deviceObject);
irp = IoBuildDeviceIoControlRequest(
IOCTL_MOUNTMGR_CREATE_POINT,
deviceObject, createPoint, createPointSize,
NULL, 0, FALSE, &event, &ioStatus);
status = IoCallDriver(deviceObject, irp);
この擬似コード サンプルの呼び出しシーケンスは、簡潔にするために簡略化されています。 より完全な擬似コードの例については、IOCTL_MOUNTMGR_CREATE_POINTを参照してください。
マウント マネージャー クライアントは、ドキュメントに記載されている任意の IOCTL_MOUNTMGR_XXX 制御コードをマウント マネージャーに送信できます (IOCTL_MOUNTMGR_CREATE_POINTなど)。
Mount Manager によって送信される I/O コントロール コード
マウント マネージャーは、IOCTL_MOUNTDEV_QUERY_DEVICE_NAMEなど、文書化されている IOCTL_MOUNTDEV_XXX 制御コードをクライアントに送信できます。