Поделиться через


Поддержка запросов Диспетчера подключений в драйвере класса хранилища

Диспетчер подключения, предоставленный системой, отвечает за управление именами томов. Для каждого тома сохраняется уникальное и окончательно определенное имя тома, даже после удаления тома из системы. Кроме того, он управляет менее постоянными именами, такими как буквы диска, которые сохраняются во время перезагрузки, но назначения которых могут изменяться при добавлении или удалении томов из системы.

Диспетчер подключения предоставляет уникальный интерфейс для каждого тома в системе, создав символьную ссылку на объект устройства тома. Так как символьные связи и объекты устройства, на которые они нацелены, не сохраняются при перезапуске системы, диспетчер подключений сохраняет имя символьной ссылки в базе данных постоянных имен в реестре.

Это имя символьной ссылки называется уникальным именем тома. Как и традиционная метка тома, она сохраняется при перезапуске системы. Как буква диска и в отличие от метки тома, это имя уникально. Формат уникальных имен томов следует, где GUID является глобально уникальным идентификатором, который идентифицирует том.

"\?? \Volume{GUID}\

База данных постоянного имени диспетчера подключения находится в разделе реестра MountDevices в системном кусте (HKLM/SYSTEM/MountDevices) реестра. Помимо уникальных имен томов диспетчер подключений также сохраняет имена точек подключения в базе данных постоянных имен. Имена точек подключения можно разделить на две категории: имена путей в стиле Win32, которые служат корневым каталогом файловой системы подключенного тома и буквами диска.

Каждое постоянное символьное имя ссылки в базе данных отображается в качестве имени значения реестра в разделе MountedDevices, сопровождаемом уникальным идентификатором. Уникальный идентификатор — это другой уникальный идентификатор тома (отличается от уникального имени тома). Он помогает определить, какие из потенциально многочисленных имен постоянных символьных ссылок ссылаются на один и тот же том.

Например, один том с уникальным именем тома **"\\?\Volume{**7603f260-142a-11d4-ac67-806d6172696f }\" может содержать сопровождающую букву диска "\DosDevices\D:" и две точки подключения "\DosDevices\C:\mymount" и "\DosDevices\E:\FilesysD\mnt". Эта комбинация создаст четыре записи в базе данных имени постоянной символьной связи диспетчера подключений: один для уникального имени тома, один для буквы диска и два для двух имен точек подключения. Все четыре записи будут совместно использовать один и тот же уникальный идентификатор. Таким образом, пользователь, просматривающий раздел реестра MountedDevices , сможет обнаружить, что все четыре постоянных имена указывают на один том.

На следующем снимке экрана показано, как постоянные имена отображаются в разделе реестра MountedDevices .

Снимок экрана, демонстрирующий, как постоянные имена отображаются в подключенном разделе реестра.

Диспетчер подключений использует механизм уведомления интерфейса устройства самонастраивающийся для оповещения о поступлении и удалении тома. Поэтому каждый клиент (то есть каждый драйвер тома, как правило, драйвер класса) должен создать интерфейс в классе интерфейса MOUNTDEV_MOUNTED_DEVICE_GUID путем вызова IoRegisterDeviceInterface , чтобы уведомить диспетчер подключения о поступлении в систему тома, которым он управляет. GUID класса интерфейса MOUNTDEV_MOUNTED_DEVICE_GUID определен в mountmgr.h.

После получения уведомления самонастраивающийся о прибытии интерфейса тома диспетчер подключения отправляет клиенту три элемента управления устройствами irPs:

В ответ на эти три ioCTLs клиент должен возвратить имя объекта объекта устройства тома (или целевое имя), расположенное в каталоге устройств дерева системных объектов (например, "\Device\HarddiskVolume1"), уникальный идентификатор тома и предлагаемое имя постоянной символьной ссылки для тома соответственно. Хотя клиенты могут игнорировать IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME, они должны предоставить уникальный идентификатор тома при получении IOCTL_MOUNTDEV_QUERY_DEVICE_NAME или IOCTL_MOUNTDEV_QUERY_UNIQUE_ID. Диспетчер подключений полностью зависит от клиента для предоставления уникального идентификатора тома. Если клиент не предоставляет его, диспетчер подключения не может назначать точки подключения, такие как буквы дисков, тому.

Если клиент оповещает диспетчер подключений о прибытии тома, но не удается указать уникальный идентификатор тома при запросе, том помещается в список неактивных подключенных устройств . При возникновении этой ситуации клиенты могут отправить IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES IOCTL диспетчеру подключений, чтобы запросить, чтобы диспетчер подключений пересканировал свой список мертвых подключенных устройств и еще одну попытку запросить клиентов в списке для уникальных идентификаторов соответствующих томов.

После получения уникального идентификатора тома для недавно появившейся тома диспетчер подключения:

  • Он выполняет поиск базы данных для всех постоянных имен, назначенных данному уникальному идентификатору.
  • Он создает символьные ссылки на том для каждого постоянного имени символьной ссылки.

Когда диспетчер подключений обнаруживает, что том сошел с линии, он удаляет символьные ссылки, указывающие на объект устройства без удаления соответствующих имен символьных ссылок в базе данных диспетчера подключений.

Сведения о том, как клиенты диспетчера подключений создают постоянные символьные имена, см. в IOCTL_MOUNTMGR_CREATE_POINT.

Коды управления ввода-вывода, отправленные клиентами Mount Manager

Диспетчер подключений публикует интерфейс, позволяющий клиентам диспетчера подключений задавать, запрашивать и удалять постоянные имена томов. Для доступа к этому интерфейсу клиенты могут получить указатель на объект устройства диспетчера подключения с помощью имени объекта MOUNTMGR_DEVICE_NAME, определенного в Mountmgr.h. Например:

    // 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_XXXX, напримерIOCTL_MOUNTMGR_CREATE_POINT.

Коды управления ввода-вывода, отправленные диспетчером подключений

Диспетчер подключений может отправлять любой из задокументированных кодов управления IOCTL_MOUNTDEV_XXXX своим клиентам, например IOCTL_MOUNTDEV_QUERY_DEVICE_NAME.